# **************************************
# --*-- coding: utf-8 --*--
# @Author  : white
# @FileName: 哑变量.py
# @Time    : 2025-08-14
# **************************************
import matplotlib.pyplot as plt
import numpy as np
import statsmodels.api as sm
import pandas as pd

"""
哑变量（Dummy Variable），也称为虚拟变量（Virtual Variable / Indicator Variable），
是统计学和机器学习中用来表示分类变量（Categorical Variable）的一种方法，
将非数值型的类别数据转换为数值型变量，以便在数学模型（比如线性回归）中使用。

为什么使用哑变量？
在很多统计模型或机器学习算法（比如线性回归、逻辑回归等）中，
模型的输入变量（特征）通常要求是数值类型（连续或离散的数字），
而不能直接处理像“男/女”、“高中/本科/研究生”、“北京/上海/广州”这样的类别（文字或无序分类）数据
比如“性别”是一个分类变量，它不是数字，不能直接放到回归模型里计算。那么我们如何让模型“理解”性别呢？
这时就需要引入哑变量，用0 和 1这样的数字来表示不同的类别
"""


def library():
    nsample = 50
    groups = np.zeros(nsample, int)
    groups[20:40] = 1
    groups[40:] = 2
    # dummy = sm.categorical(groups, drop=True)
    # 将整数分组变量 groups（取值为 0, 1, 2）转换为虚拟变量（哑变量）。
    dummy = pd.get_dummies(groups, prefix='group')
    # 生成一个从 0 到 20 的等差数列，共 50 个值，代表一个连续型解释变量（比如时间、年龄等）
    x = np.linspace(0, 20, nsample)
    # 将连续变量 x和虚拟变量 dummy按列拼接，形成一个更大的设计矩阵。
    X = np.column_stack((x, dummy))
    # 在矩阵最前面插入一列全为 1 的常数项，用于表示截距（Intercept）。
    X = sm.add_constant(X)
    #  设置真实的回归系数 5个元素分别对应着 X中的5列
    beta = [10, 1, 1, 3, 8]
    e = np.random.normal(size=nsample)
    y = np.dot(X, beta) + e

    result = sm.OLS(y, X).fit()
    print(result.summary())

    fig, ax = plt.subplots(figsize=(8, 6))
    ax.plot(x, y, 'o', label="data")
    ax.plot(x, result.fittedvalues, 'r--.', label="OLS")
    ax.legend(loc='best')
    plt.show()


def use():
    data = get_price(['000001.XSHG', '399001.XSHE'],
                     start_date='2015-01-01', end_date='2016-01-01',
                     frequency='daily',
                     fields=['close'])['close']
    x_price = data['000001.XSHG'].values
    y_price = data['399001.XSHE'].values

    x_pct, y_pct = [], []
    for i in range(1, len(x_price)):
        x_pct.append(x_price[i] / x_price[i - 1] - 1)
    for i in range(1, len(y_price)):
        y_pct.append(y_price[i] / y_price[i - 1] - 1)

    x = np.array(x_pct)
    X = sm.add_constant(x)
    y = np.array(y_pct)

    results = sm.OLS(y, X).fit()
    print(results.summary())

    fig, ax = plt.subplots(figsize=(8, 6))
    ax.plot(x, y, 'o', label="data")
    ax.plot(x, results.fittedvalues, 'r--', label="OLS")
    ax.legend(loc='best')
